#include <algorithm>
#include <cstdio>
#define lowbit(x) (x & -x)

const int N = 2e5 + 5;
int n, q, tim, val[N << 1];
int e_cnt, heads[N];

struct Edge {
  int v, nxt;
} e[N << 1];

inline void add(int u, int v) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
}

struct Node {
  int ch[2], fa, siz, tag;
  bool rev;
} tr[N];

inline void modify(int x, int v) {
  while (x <= n + q) val[x] += v, x += lowbit(x);
}

inline int query(int x) {
  int res = 0;
  while (x) res += val[x], x -= lowbit(x);
  return res;
}

inline bool iden(int x) { return tr[tr[x].fa].ch[1] == x; }

inline bool isnrt(int x) {
  return tr[tr[x].fa].ch[0] == x || tr[tr[x].fa].ch[1] == x;
}

inline void pushup(int x) {
  tr[x].siz = tr[tr[x].ch[0]].siz + tr[tr[x].ch[1]].siz + 1;
}

inline void rotate(int x) {
  bool xtofa = iden(x);
  int fa = tr[x].fa, ffa = tr[fa].fa, son = tr[x].ch[!xtofa];
  if (isnrt(fa)) tr[ffa].ch[iden(fa)] = x;
  tr[x].fa = ffa;
  tr[x].ch[!xtofa] = fa;
  tr[fa].fa = x;
  tr[fa].ch[xtofa] = son;
  if (son) tr[son].fa = fa;
  pushup(fa);
  pushup(x);
}

inline void reverse(int x) {
  std::swap(tr[x].ch[0], tr[x].ch[1]);
  tr[x].rev ^= 1;
}

inline void pushdown(int x) {
  static int ls, rs;
  ls = tr[x].ch[0], rs = tr[x].ch[1];
  if (ls) tr[ls].tag = tr[x].tag;
  if (rs) tr[rs].tag = tr[x].tag;
  if (tr[x].rev) {
    if (ls) reverse(ls);
    if (rs) reverse(rs);
    tr[x].rev = false;
  }
}

inline void pushall(int x) {
  if (isnrt(x)) pushall(tr[x].fa);
  pushdown(x);
}

inline void splay(int x) {
  pushall(x);
  for (int fa = tr[x].fa; isnrt(x); rotate(x))
    if (isnrt(fa = tr[x].fa)) rotate(iden(fa) == iden(x) ? fa : x);
}

inline void access(int x) {
  for (int y = 0; x; y = x, x = tr[x].fa) {
    splay(x);
    modify(tr[x].tag, -(tr[x].siz - tr[tr[x].ch[1]].siz));
    modify(tim, tr[x].siz - tr[tr[x].ch[1]].siz);
    tr[x].ch[1] = y;
    pushup(x);
  }
}

inline void makert(int x) { access(x), splay(x), reverse(x), tr[x].tag = tim; }

void solve(int x) {
  tr[x].siz = 1, tr[x].tag = x;
  for (int i = heads[x], v; i; i = e[i].nxt) {
    if ((v = e[i].v) != tr[x].fa) {
      tr[v].fa = x;
      solve(v);
      if (tr[v].tag > tr[x].tag) {
        tr[x].tag = tr[v].tag;
        tr[x].ch[1] = v;
        tr[x].siz = tr[v].siz + 1;
      }
    }
  }
  modify(tr[x].tag, 1);
}

inline int when(int x) {
  splay(x);
  return query(tr[x].tag) - tr[tr[x].ch[0]].siz;
}

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("testdata.in", "r", stdin);
  freopen("testdata.out", "w", stdout);
#else
  freopen("CF1137F Matches Are Not a Child's Play.in", "r", stdin);
  freopen("CF1137F Matches Are Not a Child's Play.out", "w", stdout);
#endif
#endif

  scanf("%d%d", &n, &q);
  tim = n;
  int u, v;
  for (int i = 1; i < n; ++i) {
    scanf("%d%d", &u, &v);
    add(u, v), add(v, u);
  }
  solve(n);
  char opt[8];
  for (int i = 1; i <= q; ++i) {
    scanf("%s%d", opt, &u);
    switch (opt[0]) {
      case 'u':
        ++tim, makert(u);
        break;
      case 'w':
        printf("%d\n", when(u));
        break;
      case 'c':
        scanf("%d", &v);
        printf("%d\n", when(u) < when(v) ? u : v);
        break;
    }
  }
  return 0;
}